package cn.kimmking.research.qedis.core;

import cn.kimmking.research.qedis.core.opr.*;
import lombok.Data;
import org.springframework.stereotype.Component;

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;


/**
 * qedis cache.
 *
 * @Author : kimmking(kimmking@apache.org)
 * @create 2022/12/4 00:54
 */
@Component
@Data
public class QedisCache {

    ScheduledExecutorService executor;

    CommonOperator commonOperator = new CommonOperator();
    StringOperator stringOperator = new StringOperator();
    ListOperator listOperator = new ListOperator();
    HashOperator hashOperator = new HashOperator();
    SetOperator setOperator = new SetOperator();
    ZsetOperator zsetOperator = new ZsetOperator();

    public void start() {
        executor = Executors.newSingleThreadScheduledExecutor();
        executor.scheduleAtFixedRate(AbstractOperator::updateTs, 10, 10, TimeUnit.MILLISECONDS);
    }

    public void shutdown() {
        executor.shutdown();
        if(!executor.isTerminated()) {
            try {
                if(!executor.awaitTermination(3, TimeUnit.SECONDS)){
                    executor.shutdownNow();
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
                throw new RuntimeException(e);
            }
        }
    }

    // ==================== common ========================

    public int exists(String...keys) {
        return commonOperator.exists(keys);
    }
    public int del(String...keys) {
        return commonOperator.del(keys);
    }

    public boolean expire(String key, long ttl) {
        return commonOperator.expire(key, ttl);
    }

    public long ttl(String key) {
        return commonOperator.ttl(key);
    }
    // ==================== common end ========================

    // ==================== string ========================
    public void set(String key, String value) {
        stringOperator.set(key, value);
    }

    public String get(String key) {
        return stringOperator.get(key);
    }

    public Integer strlen(String key) {
        return stringOperator.strlen(key);
    }

    // ==================== string end ========================

    // ================  list start ======================

    public int lpush(String key, String... values) {
        return listOperator.lpush(key, values);
    }

    public int rpush(String key, String... values) {
        return listOperator.rpush(key, values);
    }

    public String[] lpop(String key, int count) {
        return listOperator.lpop(key, count);
    }

    public String[] rpop(String key, int count) {
        return listOperator.rpop(key, count);
    }

    public int llen(String key) {
        return listOperator.llen(key);
    }

    public String[] lrange(String key, int start, int stop) {
        return listOperator.lrange(key, start, stop);
    }

    public String lindex(String key, int index) {
        return listOperator.lindex(key, index);
    }
    // ================  list end ======================

    // ================  hash start ======================

    public int hset(String key, String[] fields, String[] values) {
        return hashOperator.hset(key, fields, values);
    }

    public String hget(String key, String field) {
        return hashOperator.hget(key, field);
    }

    public String[] hgetall(String key) {
        return hashOperator.hgetall(key);
    }

    public String[] hmget(String key, String... fields) {
        return hashOperator.hmget(key, fields);
    }

    public int hlen(String key) {
        return hashOperator.hlen(key);
    }

    public int hexists(String key, String field) {
        return hashOperator.hexists(key, field);
    }

    public int hdel(String key, String... fields) {
        return hashOperator.hdel(key, fields);
    }

    // ================  hash end ======================


    // ================  set start ======================

    public int sadd(String key, String... values) {
        return setOperator.sadd(key, values);
    }

    public int srem(String key, String... values) {
        return setOperator.srem(key, values);
    }

    public String spop(String key) {
        return setOperator.spop(key);
    }

    public String[] smembers(String key) {
        return setOperator.smembers(key);
    }

    public int sismember(String key, String value) {
        return setOperator.sismember(key, value);
    }

    public int scard(String key) {
        return setOperator.scard(key);
    }

    // ================  set end ======================

    // ================  zset start ===================

    public int zadd(String key, String[] values, double[] scores) {
        return zsetOperator.zadd(key, values, scores);
    }

    public int zcard(String key) {
        return zsetOperator.zcard(key);
    }

    public int zcount(String key, double min, double max) {
        return zsetOperator.zcount(key, min, max);
    }

    public Double zscore(String key, String value) {
        return zsetOperator.zscore(key, value);
    }

    public Integer zrank(String key, String value) {
        return zsetOperator.zrank(key, value);
    }

    public int zrem(String key, String... values) {
        return zsetOperator.zrem(key, values);
    }

    // ================  zset end =====================

}
